package com.chenyue.cm.auth.token;

import com.alibaba.fastjson.JSON;
import com.chenyue.cm.exception.SysRuntimeException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Pattern;

public class RequestUtil {

    private static String isWxPattern = "MicroMessenger".toUpperCase();

    private static String isPhone = "Android|webOS|iPhone|iPod|BlackBerry".toUpperCase();

    private static String isIe = "msie".toUpperCase();

    /**
     * 获取用户的访问IP
     *
     * @param request
     * @return
     */
    public static String getRemoteIp(HttpServletRequest request) {
        String ip = request.getHeader("x-real-ip");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("x-forwarded-for");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 获取IP所在地
     *
     * @param ip
     * @return
     */
    @SuppressWarnings("unchecked")
    public static String getAddressByIP(String ip) {
        StringBuffer address = new StringBuffer();
        try {
            URL url = new URL("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(500);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line = null;
            StringBuffer result = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> resultMap = mapper.readValue(result.toString(), Map.class);
            if (Integer.parseInt(resultMap.get("code").toString()) == 0) {
                Map<String, String> datas = (Map<String, String>) resultMap.get("data");
                if (!"内网IP".equals(datas.get("isp"))) {
                    address.append(datas.get("country")).append(" ").append(datas.get("region")).append(" ")
                            .append(datas.get("city")).append(" ").append(datas.get("isp"));
                } else {
                    address.append(datas.get("isp"));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return address.toString();
    }

    /**
     * 判断是否是手机浏览器浏览
     *
     * @param request
     * @return
     */
    public static boolean isMobileBrowse(HttpServletRequest request) {
        String userAgent = request.getHeader("USER-AGENT").toUpperCase();
        boolean isMobielBrowse = Pattern.compile(isPhone).matcher(userAgent).find();
        return isMobielBrowse;
    }

    /**
     * 判断是否是微信进行访问
     *
     * @param request
     * @return
     */
    public static boolean isWxBrowse(HttpServletRequest request) {
        String userAgent = request.getHeader("USER-AGENT").toUpperCase();
        boolean isWxBrowse = Pattern.compile(isWxPattern).matcher(userAgent).find();
        return isWxBrowse;
    }

    /**
     * 判断是否为IE浏览器
     *
     * @param request
     * @return
     */
    public static boolean isIeBrowse(HttpServletRequest request) {
        String userAgent = request.getHeader("USER-AGENT").toUpperCase();
        boolean isIeBrowse = Pattern.compile(isIe).matcher(userAgent).find();
        return isIeBrowse;
    }

    /**
     * 获取头部token
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static String getRequestToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            if (request.getCookies() == null) {
                throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
            }
            Cookie[] tokens = request.getCookies();
            for (Cookie cookie : tokens) {
                if ("MANAGER_TOKEN".equalsIgnoreCase(cookie.getName())) {
                    token = cookie.getValue();
                    break;
                }
            }
        }
        return token;
    }

    /**
     * 从request中直接获取登录用户信息
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static LoginUserInfo getUserInfoByRequest(HttpServletRequest request) throws Exception {
        String token = RequestUtil.getRequestToken(request);
        return JWTHelper.verifyTokenReturnLoginUserInfo(token);
    }

    /**
     * 根据IP获取所在城市
     *
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    public static String getRemoteAddr(HttpServletRequest request) {
        String ip = RequestUtil.getRemoteIp(request);
        if (ip.equals("0:0:0:0:0:0:0:1") || ip.equals("127.0.0.1")) {
            return "本机测试";
        }
        StringBuffer address = new StringBuffer();
        try {
            URL url = new URL("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(500);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line = null;
            StringBuffer result = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            Map<String, Object> resultMap = JSON.parseObject(result.toString(), Map.class);
            if (Integer.parseInt(resultMap.get("code").toString()) == 0) {
                Map<String, String> datas = (Map<String, String>) resultMap.get("data");
                if (!datas.get("isp").equals("内网IP")) {
                    address.append(datas.get("country")).append(" ").append(datas.get("region")).append(" ")
                            .append(datas.get("city")).append(" ").append(datas.get("isp"));
                } else {
                    address.append(datas.get("isp"));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return address.toString();
    }


    public static void main(String[] args) {
        System.out.println(RequestUtil.getAddressByIP("127.0.0.1"));
    }
}
